﻿using System;
using System.Collections.Generic; 
using System.Text;
using System.Text.RegularExpressions;
 
using System.Drawing;
using System.Windows.Forms;
using ICSharpCode.TextEditor;
using DevelopAssistant.Service;
using DevelopAssistant.Common;

namespace DevelopAssistant.Service.MSQLIntellisense
{
    public class SqlIntellisense : IntellisenseBase
    {
        private bool uncertain;
        private bool gotoTable;

        protected Keys prevKeyCode;
        protected string uncompletedText;

        protected Label lblTooltip;

        protected SqlPromptData promptData
        {
            get
            {
                return SqlPromptDataCache.GetData(_editor.DataBaseServer); //SqlPromptDataCache.promptData;
            }
        }

        protected IntellisenseBox codeBox;

        protected IList<SqlIntellisenseBoxItem> filteredItems;

        #region 正则表达式

        protected const string RegexUserFuntions = "select\\s+\\w*$";
        protected const string RegexColumn = "(select\\stop\\s|select|set|where|and|or)\\s+(\\w|[\\w|\\w\\s+'],+|[\\w|\\w\\s+|\\r\\n],\\s+)*$";
        protected const string RegexColumnOfTable = "(\\s+|=|,)(\\w+)\\.\\w*$";//(\\s+|=)(\\w+)\\.\\w*$
        protected const string RegexJoinTables = "from\\s+(\\w+)|join\\s+(\\w+)";
        protected const string RegexMultiTalbes = "from(.+,.+)where";
        protected const string RegexNone = "((as\\s+)|((from|update|join)\\s+\\w+\\s+)|(,\\s*\\w+\\s+))\\w*$";
        protected const string RegexOn = "join\\s+\\w+\\s+o\\w*$";
        protected const string RegexSingleTable = "from\\s+(\\w+)\\s+where";
        protected const string RegexTable = "(from|update|table|join|insert into)\\s+\\w*$|from(\\s|\\w)+,\\s*\\w*$";
        protected const string RegexTables = "(from|where|and|or)\\s+\\w*$";
        protected const string RegexUpdateTable = "update\\s+(\\w+)\\s+set\\s+\\w";
        protected const string RegexWhere = "from\\s+\\w+\\s+w\\w*$";
        protected const string RegexOrderBy = "order\\s+by";
        protected const string RegexExpendColumnsForInsert = "insert into\\s+\\w+$";
        protected const string RegexStar = "\\*\\s+from\\s+(\\w+)$";

        #endregion

        public string UncompletedText
        {
            get
            {
                if (this._editor == null)
                {
                    return "";
                }
                if (this._editor.ActiveTextAreaControl.TextArea.Caret.Offset == this._editor.Text.Length)
                {
                    this.uncompletedText = this.GetLastWord(this._editor.Text);
                }
                else
                {
                    this.uncompletedText = this._editor.Text.Substring(0, this._editor.ActiveTextAreaControl.TextArea.Caret.Offset);
                    this.uncompletedText = this.GetLastWord(this.uncompletedText);
                }
                return this.uncompletedText;
            }
        }

        private string _defaultTable;
        public string DefaultTable
        {
            set { _defaultTable = value; }
            get { return _defaultTable; }
        }

        private string _providerName = "System.Data.Sql";
        public string ProviderName
        {
            get { return _providerName; }
            set { _providerName = value; }
        }

        Form _ownerForm = null;
        /// <summary>
        /// 承载该控件的Form窗体
        /// </summary>
        public virtual Form OwnerForm
        {
            get
            {
                return _ownerForm;
            }
            set
            {
                _ownerForm = value;
            }
        }

        private ICSharpCodeTextEditor _editor;
        public ICSharpCodeTextEditor Editor
        {
            set
            {
                this._editor = value;
                if (this._editor == null)
                    return;

                this._editor.ActiveTextAreaControl.TextArea.KeyDown += new System.Windows.Forms.KeyEventHandler(this.DoKeyDown);
                this._editor.ActiveTextAreaControl.TextArea.KeyUp += new System.Windows.Forms.KeyEventHandler(this.DoKeyUp);
                this._editor.ActiveTextAreaControl.TextArea.MouseClick += new MouseEventHandler(this.TextArea_MouseClick);
                this._editor.ActiveTextAreaControl.ScrollBarValueChanged += new ScrollEventHandler(this.ScrollBar_ValueChanged);
                this._editor.ActiveTextAreaControl.TextArea.DoProcessDialogKey += new DialogKeyProcessor(this.DoProcessDialogKey);

            }
            get { return _editor; }
        }

        public SqlIntellisense()
        {
            this.codeBox = (IntellisenseBox)new SqlIntellisenseBox();
            this.intellisenseBox = (Control)this.codeBox;

            this.lblTooltip = new Label();
            this.lblTooltip.ForeColor = SystemColors.ActiveCaption;
            this.lblTooltip.BackColor = SystemColors.Info;
            this.lblTooltip.Font = new Font("Arial", 9.0f, FontStyle.Regular);
            this.lblTooltip.BorderStyle = BorderStyle.FixedSingle;
            this.lblTooltip.AutoSize = true;
            this.lblTooltip.Hide();
        }

        protected void ShowTipAtCaret(string message)
        {
            this.lblTooltip.Text = message;
            this.lblTooltip.Location = this._editor.Caret.ScreenPosition;
            this.lblTooltip.Top = this.lblTooltip.Top + this._editor.Font.Height;
            this.lblTooltip.Show();
        }

        protected bool BeginWith(string s)
        {
            return s.ToLower().StartsWith(this.uncompletedText.ToLower());
        }

        protected virtual string GetLastWord(string str)
        {
            return new Regex("(\\w+(\\.|=)?$)|(\\w+\\s*,\\s*\\w*$)", RegexOptions.IgnoreCase | RegexOptions.RightToLeft).Match(str).Value;
        }

        protected virtual void CompleteText()
        {
            string str = this.codeBox.Text;
            if (this.gotoTable && Regex.IsMatch(this._editor.TextBeforeCaret, "insert into\\s+\\w+$", RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
            {
                IList<Column> columnsOfTable = this.promptData.GetColumnsOfTable(str);
                StringBuilder field_sb = new StringBuilder();
                StringBuilder values_sb = new StringBuilder();
                int num = 0;
                foreach (Column column in (IEnumerable<Column>)columnsOfTable)
                {
                    if (num > 0)
                    {
                        field_sb.Append(",");
                        values_sb.Append(",");
                    }                      
                    if (!column.Auto_Identify)
                    {
                        field_sb.Append(SnippetBase.GetColumnName(column.Name, _providerName));
                        values_sb.Append("'" + column.Name + "'");
                        ++num;
                    }
                }
                str = SnippetBase.GetColumnName(str, _providerName);
                str = string.Format("{0}\r\n(\r\n {1}\r\n)\r\nVALUES\r\n(\r\n {2}\r\n)\r\nGO", (object)str, (object)field_sb, (object)values_sb);
                this.InsertCompleteText(str, false);
            }
            else
            {
                this.InsertCompleteText(str, true);
            }            
            this.codeBox.Hide();
        }

        public static bool IsSqlOperator(int keyValue)
        {
            if (keyValue != 190 && keyValue != 188)
                return keyValue == 187;
            else
                return true;
        }

        protected void InsertCompleteText(string text,bool adds=true)
        {
            if (this.uncompletedText.Contains("."))
                this.uncompletedText = this.uncompletedText.Substring(this.uncompletedText.IndexOf('.') + 1);

            if (this.uncompletedText.Contains(","))
                this.uncompletedText = this.uncompletedText.Substring(this.uncompletedText.IndexOf(',') + 1);

            //Caret caret = this._editor.Caret;

            int startOffset = this._editor.Caret.Offset + 1; //caret.Offset + 1;
            int endOffset = startOffset;

            if (!string.IsNullOrEmpty(this.uncompletedText))
            {
                startOffset -= this.uncompletedText.Length + 1;
                endOffset--;
                if (endOffset - startOffset > 0)// if (endOffset - startOffset > 0)
                    this._editor.Document.Remove(startOffset, endOffset - startOffset);

                this._editor.TextArea.Caret.Position = this._editor.TextArea.Document.OffsetToPosition(Math.Min(startOffset, this._editor.TextArea.Document.TextLength));
            }

            this.uncompletedText = string.Empty;

            if (!string.IsNullOrEmpty(text))
            {
                if (promptData.Db.IsFunctions(text))
                {
                    var Function = promptData.Db.Functions.Find((Function f) => { if (f.Name.Equals(text)) return true; else return false; });
                    if (Function != null)
                    {
                        int num = 0;
                        string Argments = string.Empty;

                        if (Function.Parameters != null)
                        {
                            foreach (SqlParameter p in Function.Parameters)
                            {
                                if (num > 0)
                                    Argments += ",";
                                Argments += p.Name;
                                num++;
                            }
                        }
                        
                        switch (this._providerName)
                        {
                            case "System.Data.Sql":
                            case "System.Data.SQL":
                            case "System.Data.Sqlite":
                                text = text + "(" + Argments + ")";
                                break;
                            case "System.Data.PostgreSql":
                                text = "\"" + text + "\"" + "(" + Argments + ")";
                                break;
                        }
                    }
                }
                else if (!promptData.Db.IsKeyWords(text))
                {
                    if (adds)
                    {
                        switch (this._providerName)
                        {
                            case "System.Data.Sql":
                            case "System.Data.SQL":
                            case "System.Data.Sqlite":
                                text = "[" + text + "]";
                                break;
                            case "System.Data.PostgreSql":
                                text = "\"" + text + "\"";
                                break;
                        }
                    }                    
                }                
                else
                {
                    switch (text.ToUpper())
                    {
                        case "INSERT":
                            if (!this._editor.TextAfterCaret.Trim().StartsWith("INTO", StringComparison.OrdinalIgnoreCase))
                                text += " INTO";
                            break;
                        case "DELETE":
                            if (!this._editor.TextAfterCaret.Trim().StartsWith("FROM", StringComparison.OrdinalIgnoreCase))
                                text += " FROM";
                            break;
                        case "ORDER":
                            if (!this._editor.TextAfterCaret.Trim().StartsWith("BY", StringComparison.OrdinalIgnoreCase))
                                text += " BY";
                            break;
                        case "GROUP":
                            if (!this._editor.TextAfterCaret.Trim().StartsWith("BY", StringComparison.OrdinalIgnoreCase))
                                text += " BY";
                            break;
                    }
                }
            }
           
            this._editor.TextArea.InsertString(text);
        }

        private bool DoWithPromptBox(KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.End:
                    this.codeBox.SelectedIndex = this.codeBox.Items.Count - 1;
                    return false;
                case Keys.Home:
                    this.codeBox.SelectedIndex = 0;
                    return false;
                case Keys.Up:
                    if (this.codeBox.SelectedIndex > 0)
                    {
                        IntellisenseBox intellisenseBox = this.codeBox;
                        int num = intellisenseBox.SelectedIndex - 1;
                        intellisenseBox.SelectedIndex = num;
                    }
                    else
                        this.codeBox.SelectedIndex = this.codeBox.Items.Count - 1;
                    return false;
                case Keys.Down:
                    if (this.codeBox.SelectedIndex < this.codeBox.Items.Count - 1)
                    {
                        IntellisenseBox intellisenseBox = this.codeBox;
                        int num = intellisenseBox.SelectedIndex + 1;
                        intellisenseBox.SelectedIndex = num;
                    }
                    else
                        this.codeBox.SelectedIndex = 0;
                    return false;               
                default:
                    return true;
            }
        }

        private void ShowPromptBox(TextArea textArea)
        {
            if (this.codeBox != null && this.codeBox.Visible)
            {
                this.codeBox.Hide();
            }
            else
            {
                this.codeBox = (IntellisenseBox)new SqlIntellisenseBox();
                this.intellisenseBox = (Control)this.codeBox;
                textArea.Controls.Clear();
                textArea.Controls.Add((Control)this.codeBox);
                textArea.Controls.Add((Control)this.lblTooltip);
                this.codeBox.MouseDoubleClick += new MouseEventHandler(this.codeList_MouseDoubleClick);
                this.codeBox.SelectedIndexChanged += new EventHandler(this.codeList_SelectedIndexChanged);
                this.codeBox.VisibleChanged += new EventHandler(this.codeList_VisibleChanged);

            }

            if (this.uncompletedText.Contains(","))
                this.uncompletedText = this.uncompletedText.Substring(this.uncompletedText.IndexOf(',') + 1).Trim();
            this.codeBox.Hide();
            (this.codeBox as SqlIntellisenseBox).FilterItems(this.uncompletedText, this.filteredItems);
            if (this.codeBox.Items.Count == 0)
                return;
            this.codeBox.Location = this._editor.ActiveTextAreaControl.TextArea.Caret.ScreenPosition;
            IntellisenseBox intellisenseBox = this.codeBox;
            int num = intellisenseBox.Top + textArea.Font.Height;
            intellisenseBox.Top = num;
            this.codeBox.SelectedIndex = 0;
            this.codeBox.Show();
        }

        private void codeList_VisibleChanged(object sender, EventArgs e)
        {
            if (this.codeBox.Visible)
                return;
            this.lblTooltip.Hide();
        }

        private void codeList_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.codeBox.SelectedIndex < 0)
            {
                this.lblTooltip.Hide();
            }
            else
            {
                SqlIntellisenseBoxItem intellisenseBoxItem = this.codeBox.Items[this.codeBox.SelectedIndex] as SqlIntellisenseBoxItem;
                if (!string.IsNullOrEmpty(intellisenseBoxItem.TooltipText))
                {
                    this.lblTooltip.Text = intellisenseBoxItem.TooltipText;
                    this.lblTooltip.Left = this.codeBox.Right + 4;                   
                    this.lblTooltip.Top = this.codeBox.Top + intellisenseBoxItem.Bounds.Top;
                    //if (this.codeBox.SelectedIndex < (this.codeBox.Height / this.codeBox.ItemHeight)-1)
                    //    this.lblTooltip.Top = this.codeBox.Top + this.codeBox.ItemHeight * this.codeBox.SelectedIndex;
                    this.lblTooltip.Visible = true;                    
                }
                else
                {
                    this.lblTooltip.Visible = false;
                }                
            }
        }

        private void codeList_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.CompleteText();
        }

        private void TextArea_MouseClick(object sender, MouseEventArgs e)
        {
            if (this.intellisenseBox == null || !this.intellisenseBox.Visible)
                return;
            this.intellisenseBox.Hide();
        }

        protected void DoKeyDown(object sender, KeyEventArgs e)
        {
            if (AppSettings.EditorSettings.EnableIntellisense)
                return;
            if (this.codeBox == null || !this.codeBox.Visible)
                return;
            if (e.KeyCode == Keys.Space && !this.uncertain && (this.prevKeyCode != Keys.Back && this.prevKeyCode != Keys.ControlKey))
            {
                this.CompleteText();
                if (!this.uncertain)
                    return;
                this.uncertain = false;
            }
            else
            {
                if (IntellisenseBase.IsChracterOrNumberKey(e.KeyValue) || e.KeyCode == Keys.Tab || (e.KeyCode == Keys.Return || e.Shift))
                    return;
                this.codeBox.Hide();
            }
        }

        protected void DoKeyUp(object sender, KeyEventArgs e)
        {
            if (AppSettings.EditorSettings.EnableIntellisense)
            {
                if (this.codeBox != null && this.codeBox.Visible)
                {
                    if (e.KeyCode == Keys.Return || e.KeyCode == Keys.Tab || (int)e.KeyValue == 32)
                    {
                        this.CompleteText();
                        return;
                    }
                }
                if (string.IsNullOrEmpty(this.UncompletedText))
                {
                    if (this.codeBox == null || !this.codeBox.Visible)
                        return;
                    this.codeBox.Hide();
                }
                else
                {                    
                    if ((int)e.KeyValue == 38 || (int)e.KeyValue == 40 
                        || (int)e.KeyValue == 13 || (int)e.KeyValue == 32)
                        return;

                    if ((e.KeyCode == Keys.Up || e.KeyCode == Keys.Down
                     || e.KeyCode == Keys.Home || e.KeyCode == Keys.End))
                        return;

                    if (e.Control && ((int)e.KeyValue == 67 || (int)e.KeyValue == 86))
                        return;

                    TextArea textArea = sender as TextArea;
                    this.filteredItems = this.GetPromptItems((char)e.KeyValue, textArea.Document.TextContent); //this._editor.Text.Substring(0, textArea.Caret.Offset)
                    this.ShowPromptBox(textArea);

                }

            }
        }

        protected bool DoProcessDialogKey(Keys keyData)
        {
            if (AppSettings.EditorSettings.EnableIntellisense)
            {
                KeyEventArgs e = new KeyEventArgs(keyData);

                if ((e.KeyCode == Keys.Up || e.KeyCode == Keys.Down
                      || e.KeyCode == Keys.Home || e.KeyCode == Keys.End))
                {
                    if (this.codeBox != null && this.codeBox.Visible)
                    {
                        return !DoWithPromptBox(e);                        
                    }
                }

                return (e.KeyCode == Keys.Return || e.KeyCode == Keys.Tab || e.KeyCode == Keys.Space)
                    && (this.intellisenseBox != null && this.intellisenseBox.Visible);
            }
            else
            {
                return false;
            }        
             
        }

        protected static string[] GetTableNames(string sql)
        {
            UnrepeatableList<string> tabls = new UnrepeatableList<string>();
            Match match1 = Regex.Match(sql, "from\\s+(\\w+)\\s+where", RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
            if (match1.Success)
            {
                tabls.Add(match1.Result("$1"));
            }
            Match match2 = Regex.Match(sql, "update\\s+(\\w+)\\s+set", RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
            if (match2.Success)
            {
                tabls.Add(match2.Result("$1"));
            }
            else
            {
                Match match3 = Regex.Match(sql, "from(.+,.+)where", RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
                if (match3.Success)
                {
                    string[] strArray = match3.Result("$1").Trim().Split(new char[1]
            {
              ','
            });
                    for (int index = 0; index < strArray.Length; ++index)
                        tabls.Add(strArray[index].Trim());

                }
                else
                {
                    MatchCollection matchCollection = Regex.Matches(sql, "from\\s+(\\w+)|join\\s+(\\w+)", RegexOptions.IgnoreCase | RegexOptions.RightToLeft);

                    foreach (Match match4 in matchCollection)
                        tabls.Add(match4.Result("$1$2"));

                }
            }
            return tabls.ToArray();
        }

        protected static string GetTableNameByAlias(string sql, string tableAlias)
        {
            string tabls = string.Empty;
            try
            {
                string pattern1 = string.Format("(from|join)\\s+(\\w+)\\s+{0}\\s*", (object)tableAlias);
                Match match1 = Regex.Match(sql, pattern1, RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
                if (match1.Success)
                    tabls += match1.Result("$2");
                string pattern2 = string.Format(",\\s*(\\w+)\\s+{0}\\s*", (object)tableAlias);
                Match match2 = Regex.Match(sql, pattern2, RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
                if (match2.Success)
                    tabls += "," + match2.Result("$1");
                string pattern3 = string.Format("\\s+(\\w+)\\s+as\\s+{0}\\s*", (object)tableAlias);
                Match match3 = Regex.Match(sql, pattern3, RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
                if (match3.Success)
                    tabls += "," + match3.Result("$1");
                string pattern4 = string.Format("\\(.*\\)\\s+{0}\\s*", (object)tableAlias);
                Match match4 = Regex.Match(sql, pattern4, RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
                if (match4.Success)
                    tabls = string.Join(",", GetTableNames(match4.Groups[0].Value));   
            }
            catch  
            {

            }
            return tabls;               
        }

        protected static List<SqlIntellisenseBoxItem> GetListWithSingleKeyWord(string word)
        {
            List<SqlIntellisenseBoxItem> list = new List<SqlIntellisenseBoxItem>();
            SqlIntellisenseBoxItem intellisenseBoxItem = new SqlIntellisenseBoxItem(word, string.Empty, SqlIntellisenseBox.Instance.GetImageIndex(SqlPromptType.Keyword));
            list.Add(intellisenseBoxItem);
            return list;
        }

        protected static IList<SqlIntellisenseBoxItem> JoinLists(IList<SqlIntellisenseBoxItem> Source, IList<SqlIntellisenseBoxItem> List)
        {
            foreach (SqlIntellisenseBoxItem Item in List)
            {
                Source.Add(Item);
            }
            return Source;
        }

        protected virtual IList<SqlIntellisenseBoxItem> GetPromptItems(char keyValue, string sqlText)
        {
            #region 获取提示项

            string textaftercaret = _editor.TextAfterCaret;
            if (!string.IsNullOrEmpty(textaftercaret))
            {
                textaftercaret = textaftercaret.Replace("\"", "").Replace("[", "").Replace("]", "");
                textaftercaret = textaftercaret.Replace("\r\n", "\t").Replace("\t\t\t\t", "\t").Replace("\t\t\t", "\t").Replace("\t\t", "\t").Trim('\t');
            }

            string textbeforecaret = _editor.TextBeforeCaret;
            if (!string.IsNullOrEmpty(textbeforecaret))
            {
                textbeforecaret = textbeforecaret.Replace("\"", "").Replace("[", "").Replace("]", "");
                textbeforecaret = textbeforecaret.Replace("\r\n", "\t").Replace("\t\t\t\t", "\t").Replace("\t\t\t", "\t").Replace("\t\t", "\t").Trim('\t');
            }

            sqlText = sqlText.Replace("\"", "").Replace("[", "").Replace("]", "").Replace("\r\n", "\t").Replace("\n", " ").Replace("\t\t\t\t", "\t").Replace("\t\t\t", "\t").Replace("\t\t", "\t").Trim('\t');

            if (Regex.IsMatch(textbeforecaret, RegexWhere, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
            {
                return this.promptData.GetItems(SqlPromptType.Keyword | SqlPromptType.SysFunction | SqlPromptType.UserFunction);
            }
            else if (Regex.IsMatch(textbeforecaret, RegexUserFuntions, RegexOptions.IgnoreCase))
            {
                string[] tableNames = null;                
                if (Regex.IsMatch(sqlText, RegexTables, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                {
                    tableNames = SqlIntellisense.GetTableNames(textaftercaret);
                    return JoinLists(this.promptData.GetColumnItems(tableNames), this.promptData.GetItems(SqlPromptType.Keyword | SqlPromptType.UserFunction));
                }
                else if (Regex.IsMatch(textaftercaret, RegexTables, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                {
                    tableNames = SqlIntellisense.GetTableNames(textaftercaret);
                    return JoinLists(this.promptData.GetColumnItems(tableNames), this.promptData.GetItems(SqlPromptType.Keyword | SqlPromptType.UserFunction));
                }
                else if (Regex.IsMatch(textbeforecaret, RegexColumn, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                {
                    tableNames = SqlIntellisense.GetTableNames(textaftercaret);
                    return JoinLists(this.promptData.GetColumnItems(tableNames), this.promptData.GetItems(SqlPromptType.Keyword | SqlPromptType.UserFunction));
                }
                else
                    return this.promptData.GetItems(SqlPromptType.Keyword | SqlPromptType.UserFunction);           
            }
            else
            {
                if (Regex.IsMatch(textbeforecaret, RegexOn, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                    return (IList<SqlIntellisenseBoxItem>)SqlIntellisense.GetListWithSingleKeyWord("ON");
                if (Regex.IsMatch(textbeforecaret, RegexNone, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                {
                    this.uncertain = true;
                    return (IList<SqlIntellisenseBoxItem>)this.promptData.GetItems(SqlPromptType.Keyword);
                }
                else if (Regex.IsMatch(textbeforecaret, RegexTable, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                {
                    this.gotoTable = true;
                    return (IList<SqlIntellisenseBoxItem>)this.promptData.GetItems(SqlPromptType.Table | SqlPromptType.View | SqlPromptType.Procedure );
                }
                else
                {
                    if (Regex.IsMatch(textbeforecaret, RegexColumnOfTable, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                    {
                        Match match = Regex.Match(textbeforecaret, RegexColumnOfTable, RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
                        string tableAlias = match.Result("$2");
                        string tableNameByAlias = SqlIntellisense.GetTableNameByAlias(textbeforecaret, tableAlias);
                        if(string.IsNullOrWhiteSpace(tableNameByAlias))
                        {
                            tableNameByAlias = SqlIntellisense.GetTableNameByAlias(textaftercaret, tableAlias);
                        }
                        if (!string.IsNullOrEmpty(tableNameByAlias))
                            return this.promptData.GetColumnItemsOfTables(tableNameByAlias);
                    }
                    else
                    {
                        string[] tableNames = null;
                        if (!Regex.IsMatch(sqlText, RegexColumn, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                        {
                            if (Regex.IsMatch(sqlText, RegexTables, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                            {
                                tableNames = SqlIntellisense.GetTableNames(sqlText);
                                return JoinLists(this.promptData.GetColumnItems(tableNames),
                                    this.promptData.GetItems(SqlPromptType.Keyword)
                                    );
                            }
                            else if (Regex.IsMatch(textaftercaret, RegexTables, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                            {
                                tableNames = SqlIntellisense.GetTableNames(textaftercaret);
                                return JoinLists(this.promptData.GetColumnItems(tableNames),                                    
                                    this.promptData.GetItems(SqlPromptType.Keyword)
                                    );
                            }
                            else if (Regex.IsMatch(textbeforecaret, RegexTables, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                            {
                                tableNames = SqlIntellisense.GetTableNames(textbeforecaret);
                                return this.promptData.GetColumnItems(tableNames);
                            }
                            else if (Regex.IsMatch(textbeforecaret, RegexColumn, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                            {
                                tableNames = SqlIntellisense.GetTableNames(sqlText);
                                return JoinLists(this.promptData.GetColumnItems(tableNames), this.promptData.GetItems(SqlPromptType.UserFunction));
                            }
                            else if (Regex.IsMatch(sqlText, RegexOrderBy, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                            {
                                tableNames = SqlIntellisense.GetTableNames(sqlText);
                                return JoinLists(this.promptData.GetColumnItems(tableNames), this.promptData.GetItems(SqlPromptType.Keyword | SqlPromptType.UserFunction));
                            }
                            else if (Regex.IsMatch(sqlText, RegexUpdateTable, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                            {
                                tableNames = SqlIntellisense.GetTableNames(sqlText);
                                return this.promptData.GetColumnItems(tableNames);
                            }
                            else if (Regex.IsMatch(sqlText, RegexWhere, RegexOptions.IgnoreCase | RegexOptions.RightToLeft))
                            {
                                tableNames = SqlIntellisense.GetTableNames(sqlText);
                                return this.promptData.GetColumnItems(tableNames);
                            }
                            return (IList<SqlIntellisenseBoxItem>)this.promptData.GetItems(SqlPromptType.Keyword | SqlPromptType.UserFunction);
                        }
                        else
                        {
                            tableNames = SqlIntellisense.GetTableNames(_editor.DText);
                            if (tableNames != null && tableNames.Length > 0)
                            {
                                return JoinLists(this.promptData.GetColumnItems(tableNames), this.promptData.GetItems(SqlPromptType.Keyword));
                            }
                        }

                        if (!string.IsNullOrEmpty(this._defaultTable))
                            return this.promptData.GetColumns(this._defaultTable);
                        else
                            return (IList<SqlIntellisenseBoxItem>)null;
                    }
                }

                return null;

            }

            #endregion
        }

        public void SetPromptStyle(Color ForeColor, Color BackColor, Font Font)
        {
            this.lblTooltip.ForeColor = ForeColor;
            this.lblTooltip.BackColor = BackColor;
            this.lblTooltip.Font = Font;
        }
    
    }

}
